package com.cryptoneedle.garden.service.garden.dwd;


import cn.hutool.v7.core.bean.BeanUtil;
import com.cryptoneedle.garden.entity.garden.doris.DorisColumn;
import com.cryptoneedle.garden.entity.garden.doris.DorisTable;
import com.cryptoneedle.garden.entity.garden.dwd.DwdColumn;
import com.cryptoneedle.garden.entity.garden.dwd.DwdTable;
import com.cryptoneedle.garden.service.crud.garden.doris.*;
import com.google.common.collect.Maps;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * <p>description:  </p>
 *
 * @author CryptoNeedle
 * @date 2025-09-26
 */
@Service
@Slf4j
public class DwdSyncService {

    @Resource
    private DwdSyncService dwdSyncService;

    @Autowired
    private AddDorisService add;
    @Autowired
    private DeleteDorisService delete;
    @Autowired
    private FoundDorisService select;
    @Autowired
    private PatchDorisService patch;
    @Autowired
    private SaveDorisService save;

    public void syncDwd(String catalogName, String databaseName) {
        dwdSyncService.syncTable(catalogName, databaseName);
        dwdSyncService.syncColumn(catalogName, databaseName);
    }

    public void syncTable(String catalogName, String databaseName) {
        // 查询所有
        List<DwdTable> originList = select.dwdTables();
        Map<String, DwdTable> originMap = Maps.uniqueIndex(originList, DwdTable::tableKeyString);

        // 待同步数据
        List<DorisTable> dorisDealList = select.dorisTables(catalogName, databaseName);
        Map<String, DorisTable> dealMap = Maps.uniqueIndex(dorisDealList, DorisTable::tableKeyString);
        List<DwdTable> dealList = dorisDealList
                .stream()
                .map(deal -> BeanUtil.copyProperties(deal, DwdTable.class))
                .toList();

        // 新增数据
        List<DwdTable> addList = dealList.stream().filter(deal -> !originMap.containsKey(deal.tableKeyString())).toList();

        // 保存数据 由于 origin 包含 deal 所有字段，此处使用 originList 作为驱动列表并直接通过属性拷贝赋值
        List<DwdTable> saveList = originList
                .stream()
                .filter(origin -> dealMap.containsKey(origin.tableKeyString()))
                .peek(origin -> {
                    DorisTable deal = dealMap.get(origin.tableKeyString());
                    origin.setCatalogName(deal.getCatalogName())
                            .setDatabaseName(deal.getDatabaseName())
                            .setTableName(deal.getTableName())
                            .setTableType(deal.getTableType())
                            .setStorageFormat(deal.getStorageFormat())
                            .setInvertedIndexStorageFormat(deal.getInvertedIndexStorageFormat())
                            .setEngine(deal.getEngine())
                            .setTableRows(deal.getTableRows())
                            .setAvgRowLength(deal.getAvgRowLength())
                            .setDataLength(deal.getDataLength())
                            .setCreateTime(deal.getCreateTime())
                            .setUpdateTime(deal.getUpdateTime())
                            .setTableCollation(deal.getTableCollation())
                            .setTableComment(deal.getTableComment());
                })
                .toList();

        // 移除数据
        List<DwdTable> removeList = originList.stream().filter(item -> !dealMap.containsKey(item.tableKeyString())).toList();

        add.dwdTables(addList);
        save.dwdTables(saveList);
        delete.dwdTables(removeList);
    }

    public void syncColumn(String catalogName, String databaseName) {
        // 查询所有
        List<DwdColumn> originList = select.dwdColumns();
        Map<String, DwdColumn> originMap = Maps.uniqueIndex(originList, DwdColumn::columnKeyString);

        // 待同步数据
        List<DorisColumn> dorisDealList = select.dorisColumns(catalogName, databaseName);
        Map<String, DorisColumn> dealMap = Maps.uniqueIndex(dorisDealList, DorisColumn::columnKeyString);
        List<DwdColumn> dealList = dorisDealList
                .stream()
                .map(deal -> BeanUtil.copyProperties(deal, DwdColumn.class))
                .toList();

        // 新增数据
        List<DwdColumn> addList = dealList.stream().filter(deal -> !originMap.containsKey(deal.columnKeyString())).toList();

        // 保存数据 由于 origin 包含 deal 所有字段，此处使用 originList 作为驱动列表并直接通过属性拷贝赋值
        List<DwdColumn> saveList = originList
                .stream()
                .filter(origin -> dealMap.containsKey(origin.columnKeyString()))
                .peek(origin -> {
                    DorisColumn deal = dealMap.get(origin.columnKeyString());
                    origin.setCatalogName(deal.getCatalogName())
                            .setDatabaseName(deal.getDatabaseName())
                            .setTableName(deal.getTableName())
                            .setColumnName(deal.getColumnName())
                            .setOrdinalPosition(deal.getOrdinalPosition())
                            .setColumnDefault(deal.getColumnDefault())
                            .setDataType(deal.getDataType())
                            .setCharacterMaximumLength(deal.getCharacterMaximumLength())
                            .setCharacterOctetLength(deal.getCharacterOctetLength())
                            .setNumericPrecision(deal.getNumericPrecision())
                            .setNumericScale(deal.getNumericScale())
                            .setDatetimePrecision(deal.getDatetimePrecision())
                            .setColumnType(deal.getColumnType())
                            .setColumnKey(deal.getColumnKey())
                            .setExtra(deal.getExtra())
                            .setColumnComment(deal.getColumnComment())
                            .setColumnSize(deal.getColumnSize())
                            .setDecimalDigits(deal.getDecimalDigits());
                })
                .toList();

        // 移除数据
        List<DwdColumn> removeList = originList.stream().filter(item -> !dealMap.containsKey(item.columnKeyString())).toList();

        add.dwdColumns(addList);
        save.dwdColumns(saveList);
        delete.dwdColumns(removeList);
    }

    public void syncColumn(String catalogName, String databaseName, String tableName) {
        // 查询所有
        List<DwdColumn> originList = select.dwdColumns(catalogName, databaseName, tableName);
        Map<String, DwdColumn> originMap = Maps.uniqueIndex(originList, DwdColumn::columnKeyString);

        // 待同步数据
        List<DorisColumn> dorisDealList = select.dorisColumns(catalogName, databaseName, tableName);
        Map<String, DorisColumn> dealMap = Maps.uniqueIndex(dorisDealList, DorisColumn::columnKeyString);
        List<DwdColumn> dealList = dorisDealList
                .stream()
                .map(deal -> BeanUtil.copyProperties(deal, DwdColumn.class))
                .toList();

        // 新增数据
        List<DwdColumn> addList = dealList.stream().filter(deal -> !originMap.containsKey(deal.columnKeyString())).toList();

        // 保存数据 由于 origin 包含 deal 所有字段，此处使用 originList 作为驱动列表并直接通过属性拷贝赋值
        List<DwdColumn> saveList = originList
                .stream()
                .filter(origin -> dealMap.containsKey(origin.columnKeyString()))
                .peek(origin -> {
                    DorisColumn deal = dealMap.get(origin.columnKeyString());
                    origin.setCatalogName(deal.getCatalogName())
                            .setDatabaseName(deal.getDatabaseName())
                            .setTableName(deal.getTableName())
                            .setColumnName(deal.getColumnName())
                            .setOrdinalPosition(deal.getOrdinalPosition())
                            .setColumnDefault(deal.getColumnDefault())
                            .setDataType(deal.getDataType())
                            .setCharacterMaximumLength(deal.getCharacterMaximumLength())
                            .setCharacterOctetLength(deal.getCharacterOctetLength())
                            .setNumericPrecision(deal.getNumericPrecision())
                            .setNumericScale(deal.getNumericScale())
                            .setDatetimePrecision(deal.getDatetimePrecision())
                            .setColumnType(deal.getColumnType())
                            .setColumnKey(deal.getColumnKey())
                            .setExtra(deal.getExtra())
                            .setColumnComment(deal.getColumnComment())
                            .setColumnSize(deal.getColumnSize())
                            .setDecimalDigits(deal.getDecimalDigits());
                })
                .toList();

        // 移除数据
        List<DwdColumn> removeList = originList.stream().filter(item -> !dealMap.containsKey(item.columnKeyString())).toList();

        add.dwdColumns(addList);
        save.dwdColumns(saveList);
        delete.dwdColumns(removeList);
    }
}